import sys
import json
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, 
                            QTableWidget, QTableWidgetItem, QHeaderView, QLabel, QLineEdit, QComboBox, 
                            QDateEdit, QMessageBox, QStackedWidget, QStatusBar, QAction, QFileDialog,
                            QAbstractItemView, QFrame, QDialog)
from PyQt5.QtCore import Qt, QDate, QPropertyAnimation, QEasingCurve, QSize, QPoint
from PyQt5.QtGui import QFont, QIcon, QColor, QPalette, QLinearGradient, QPainter, QPixmap, QPen

class AnimatedButton(QPushButton):
    def __init__(self, text, parent=None):
        super().__init__(text, parent)
        self.setCursor(Qt.PointingHandCursor)
        self.setStyleSheet("""
            QPushButton {
                background-color: #5c7cfa;
                color: white;
                border: none;
                border-radius: 15px;
                padding: 12px 24px;
                font-size: 14px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #4263eb;
            }
            QPushButton:pressed {
                background-color: #364fc7;
            }
        """)
        # 简单按钮动画
        self._animation = QPropertyAnimation(self, b"pos")
        self._animation.setDuration(200)
        self._animation.setEasingCurve(QEasingCurve.OutQuad)
    
    def enterEvent(self, event):
        # 动画效果 - 轻微上移
        self._animation.stop()
        self._animation.setStartValue(self.pos())
        self._animation.setEndValue(self.pos() + QPoint(0, -3))
        self._animation.start()
        super().enterEvent(event)
    
    def leaveEvent(self, event):
        # 动画效果 - 恢复原位
        self._animation.stop()
        self._animation.setStartValue(self.pos())
        self._animation.setEndValue(self.pos() - QPoint(0, -3))
        self._animation.start()
        super().leaveEvent(event)

class GradientHeader(QLabel):
    def __init__(self, text, parent=None):
        super().__init__(text, parent)
        self.setAlignment(Qt.AlignCenter)
        self.setFont(QFont("Arial", 18, QFont.Bold))
        self.setMinimumHeight(60)
        
    def paintEvent(self, event):
        painter = QPainter(self)
        gradient = QLinearGradient(0, 0, self.width(), self.height())
        gradient.setColorAt(0, QColor("#5c7cfa"))
        gradient.setColorAt(1, QColor("#3b5bdb"))
        painter.fillRect(self.rect(), gradient)
        
        painter.setPen(Qt.white)
        painter.drawText(self.rect(), Qt.AlignCenter, self.text())
        
        # 绘制顶部装饰线
        painter.setPen(QPen(QColor("#748ffc"), 3))
        painter.drawLine(0, 0, self.width(), 0)
        
        super().paintEvent(event)

class QSOLogger(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("HamRadio 通联日志管理系统")
        self.setGeometry(100, 100, 1800, 1000)
        self.setMinimumSize(1000, 700)
        
        # 设置应用图标
        self.setWindowIcon(QIcon(self.create_app_icon()))
        
        # 初始化数据
        self.data_file = "qsolog.json"
        self.data = self.load_data()
        
        # 清理数据
        self.clean_data()
        
        # 创建UI
        self.init_ui()
        
        # 状态栏
        self.statusBar().showMessage(f"已加载 {len(self.data)} 条通联记录")
        
    def create_app_icon(self):
        # 创建简单的应用图标
        pixmap = QPixmap(64, 64)
        pixmap.fill(Qt.transparent)
        painter = QPainter(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        
        # 绘制背景
        painter.setBrush(QColor("#5c7cfa"))
        painter.drawEllipse(2, 2, 60, 60)
        
        # 绘制天线
        painter.setPen(QPen(Qt.white, 4))
        painter.drawLine(32, 15, 32, 50)
        painter.drawLine(15, 32, 50, 32)
        
        # 绘制信号波形
        painter.setPen(QPen(Qt.white, 2))
        painter.drawArc(10, 10, 44, 44, 30 * 16, 120 * 16)
        painter.drawArc(5, 5, 54, 54, 20 * 16, 140 * 16)
        
        painter.end()
        return pixmap
    
    def clean_data(self):
        """清理数据中的状态值不一致问题"""
        valid_sent_statuses = ["未发送", "已发送", "已确认"]
        valid_recv_statuses = ["未收到", "已收到", "已确认"]
        
        for record in self.data:
            # 确保发送状态是有效值
            if record["qsl_sent"] not in valid_sent_statuses:
                # 尝试修复常见问题
                if record["qsl_sent"] == "已收到":
                    record["qsl_sent"] = "已发送"
                else:
                    record["qsl_sent"] = "未发送"
            
            # 确保接收状态是有效值
            if record["qsl_recv"] not in valid_recv_statuses:
                # 尝试修复常见问题
                if record["qsl_recv"] == "已发送":
                    record["qsl_recv"] = "已收到"
                else:
                    record["qsl_recv"] = "未收到"
        
        self.save_data()
        
    def init_ui(self):
        # 创建主部件和布局
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        main_layout = QVBoxLayout(main_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        
        # 创建标题栏
        header = GradientHeader("HamLogger 通联日志管理软件")
        main_layout.addWidget(header)
        
        # 创建主内容区域
        content_widget = QWidget()
        content_layout = QHBoxLayout(content_widget)
        content_layout.setContentsMargins(20, 20, 20, 20)
        content_layout.setSpacing(20)
        
        # 左侧导航栏
        nav_frame = QFrame()
        nav_frame.setFixedWidth(200)
        nav_frame.setStyleSheet("""
            QFrame {
                background-color: #f8f9fa;
                border-radius: 15px;
                padding: 15px;
                border: 1px solid #dee2e6;
            }
        """)
        nav_layout = QVBoxLayout(nav_frame)
        nav_layout.setAlignment(Qt.AlignTop)
        nav_layout.setSpacing(15)
        
        # 导航按钮
        self.btn_log = AnimatedButton("通联日志")
        self.btn_log.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(0))
        nav_layout.addWidget(self.btn_log)
        
        self.btn_add = AnimatedButton("添加记录")
        self.btn_add.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(1))
        nav_layout.addWidget(self.btn_add)
        
        self.btn_stats = AnimatedButton("统计信息")
        self.btn_stats.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(2))
        nav_layout.addWidget(self.btn_stats)
        
        nav_layout.addStretch()
        
        # 添加导出按钮
        self.btn_export = AnimatedButton("导出数据")
        self.btn_export.clicked.connect(self.export_data)
        nav_layout.addWidget(self.btn_export)
        
        self.btn_about = AnimatedButton("关于软件")
        self.btn_about.clicked.connect(self.show_about)
        nav_layout.addWidget(self.btn_about)
        
        content_layout.addWidget(nav_frame)
        
        # 右侧内容区域
        self.stacked_widget = QStackedWidget()
        content_layout.addWidget(self.stacked_widget, 1)
        
        # 页面1：通联日志
        self.log_page = self.create_log_page()
        self.stacked_widget.addWidget(self.log_page)
        
        # 页面2：添加记录
        self.add_page = self.create_add_page()
        self.stacked_widget.addWidget(self.add_page)
        
        # 页面3：统计信息
        self.stats_page = self.create_stats_page()
        self.stacked_widget.addWidget(self.stats_page)
        
        main_layout.addWidget(content_widget, 1)
        
        # 创建菜单栏
        self.create_menus()
    
    def create_menus(self):
        menubar = self.menuBar()
        menubar.setStyleSheet("""
            QMenuBar {
                background-color: #edf2ff;
                padding: 5px;
                border-bottom: 1px solid #dbe4ff;
            }
            QMenuBar::item {
                padding: 5px 10px;
                background: transparent;
                border-radius: 4px;
            }
            QMenuBar::item:selected {
                background: #dbe4ff;
            }
            QMenuBar::item:pressed {
                background: #bac8ff;
            }
        """)
        
        # 文件菜单
        file_menu = menubar.addMenu("文件")
        
        export_action = QAction("导出数据", self)
        export_action.triggered.connect(self.export_data)
        file_menu.addAction(export_action)
        
        import_action = QAction("导入数据", self)
        import_action.triggered.connect(self.import_data)
        file_menu.addAction(import_action)
        
        file_menu.addSeparator()
        
        exit_action = QAction("退出", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 帮助菜单
        help_menu = menubar.addMenu("帮助")
        
        about_action = QAction("关于", self)
        about_action.triggered.connect(self.show_about)
        help_menu.addAction(about_action)
    
    def create_log_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(0, 0, 0, 0)
        
        # 搜索栏
        search_frame = QFrame()
        search_frame.setStyleSheet("""
            QFrame {
                background-color: #edf2ff;
                border-radius: 10px;
                padding: 15px;
                border: 1px solid #dbe4ff;
            }
        """)
        search_layout = QHBoxLayout(search_frame)
        
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("搜索呼号、频率或备注...")
        self.search_input.setStyleSheet("""
            QLineEdit {
                border: 2px solid #dbe4ff;
                border-radius: 8px;
                padding: 8px 12px;
                font-size: 14px;
            }
            QLineEdit:focus {
                border-color: #5c7cfa;
            }
        """)
        self.search_input.textChanged.connect(self.filter_logs)
        
        search_btn = AnimatedButton("搜索")
        search_btn.setFixedWidth(100)
        search_btn.clicked.connect(self.filter_logs)
        
        search_layout.addWidget(self.search_input, 1)
        search_layout.addWidget(search_btn)
        
        layout.addWidget(search_frame)
        
        # 表格
        self.table = QTableWidget()
        self.table.setStyleSheet("""
            QTableWidget {
                background-color: white;
                border: 1px solid #dee2e6;
                border-radius: 10px;
                gridline-color: #e9ecef;
                font-size: 14px;
                selection-background-color: #dbe4ff;
                selection-color: black;
            }
            QHeaderView::section {
                background-color: #5c7cfa;
                color: white;
                font-weight: bold;
                padding: 8px;
                border: none;
            }
            QTableWidget::item {
                padding: 8px;
            }
            QTableWidget::item:selected {
                background-color: #dbe4ff;
                color: black;
            }
        """)
        self.table.setColumnCount(11)
        self.table.setHorizontalHeaderLabels([
            "ID", "呼号", "日期", "时间", "模式", "波段", "频率", 
            "发送报告", "接收报告", "QSL发送", "QSL接收", "备注"
        ])
        
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSortingEnabled(True)
        
        # 设置列宽
        self.table.setColumnWidth(0, 50)   # ID
        self.table.setColumnWidth(1, 100)  # 呼号
        self.table.setColumnWidth(2, 100)  # 日期
        self.table.setColumnWidth(3, 80)   # 时间
        self.table.setColumnWidth(4, 70)   # 模式
        self.table.setColumnWidth(5, 60)   # 波段
        self.table.setColumnWidth(6, 90)   # 频率
        self.table.setColumnWidth(7, 90)   # 发送报告
        self.table.setColumnWidth(8, 90)   # 接收报告
        self.table.setColumnWidth(9, 80)   # QSL发送
        self.table.setColumnWidth(10, 80)  # QSL接收
        
        layout.addWidget(self.table, 1)
        
        # 操作按钮
        btn_frame = QFrame()
        btn_layout = QHBoxLayout(btn_frame)
        
        self.edit_btn = AnimatedButton("编辑记录")
        self.edit_btn.setEnabled(False)
        self.edit_btn.clicked.connect(self.edit_record)
        btn_layout.addWidget(self.edit_btn)
        
        self.delete_btn = AnimatedButton("删除记录")
        self.delete_btn.setEnabled(False)
        self.delete_btn.clicked.connect(self.delete_record)
        btn_layout.addWidget(self.delete_btn)
        
        self.update_qsl_btn = AnimatedButton("更新QSL状态")
        self.update_qsl_btn.setEnabled(False)
        self.update_qsl_btn.clicked.connect(self.update_qsl_status)
        btn_layout.addWidget(self.update_qsl_btn)
        
        btn_layout.addStretch()
        
        self.refresh_btn = AnimatedButton("刷新数据")
        self.refresh_btn.clicked.connect(self.refresh_table)
        btn_layout.addWidget(self.refresh_btn)
        
        layout.addWidget(btn_frame)
        
        # 连接表格选择信号
        self.table.selectionModel().selectionChanged.connect(self.on_row_selected)
        
        # 填充表格
        self.refresh_table()
        
        return page
    
    def create_add_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setAlignment(Qt.AlignTop)
        
        title = QLabel("添加通联记录")
        title.setFont(QFont("Arial", 16, QFont.Bold))
        title.setStyleSheet("color: #3b5bdb; margin-bottom: 20px;")
        layout.addWidget(title)
        
        form_frame = QFrame()
        form_frame.setStyleSheet("""
            QFrame {
                background-color: #f8f9fa;
                border-radius: 15px;
                padding: 25px;
                border: 1px solid #dee2e6;
            }
        """)
        form_layout = QVBoxLayout(form_frame)
        
        # 呼号
        call_layout = QHBoxLayout()
        call_label = QLabel("呼号:")
        call_label.setFont(QFont("Arial", 12))
        call_label.setFixedWidth(110)
        self.call_input = QLineEdit()
        self.call_input.setPlaceholderText("请输入呼号")
        call_layout.addWidget(call_label)
        call_layout.addWidget(self.call_input, 1)
        form_layout.addLayout(call_layout)
        
        # 日期和时间
        datetime_layout = QHBoxLayout()
        
        date_layout = QHBoxLayout()
        date_label = QLabel("日期:")
        date_label.setFont(QFont("Arial", 12))
        date_label.setFixedWidth(110)
        self.date_input = QDateEdit()
        self.date_input.setDate(QDate.currentDate())
        self.date_input.setCalendarPopup(True)
        self.date_input.setStyleSheet("padding: 6px;")
        date_layout.addWidget(date_label)
        date_layout.addWidget(self.date_input, 1)
        datetime_layout.addLayout(date_layout)
        
        time_layout = QHBoxLayout()
        time_label = QLabel("时间:")
        time_label.setFont(QFont("Arial", 12))
        time_label.setFixedWidth(110)
        self.time_input = QLineEdit()
        self.time_input.setPlaceholderText("HH:MM")
        time_layout.addWidget(time_label)
        time_layout.addWidget(self.time_input, 1)
        datetime_layout.addLayout(time_layout)
        
        form_layout.addLayout(datetime_layout)
        
        # 模式、波段、频率
        mode_layout = QHBoxLayout()
        
        # 模式
        mode_field = QHBoxLayout()
        mode_label = QLabel("模式:")
        mode_label.setFont(QFont("Arial", 12))
        mode_label.setFixedWidth(110)
        self.mode_combo = QComboBox()
        self.mode_combo.addItems(["SSB", "CW", "FT8", "PSK31", "RTTY", "SSTV", "AM", "FM"])
        self.mode_combo.setStyleSheet("padding: 6px;")
        mode_field.addWidget(mode_label)
        mode_field.addWidget(self.mode_combo, 1)
        mode_layout.addLayout(mode_field)
        
        # 波段
        band_field = QHBoxLayout()
        band_label = QLabel("波段:")
        band_label.setFont(QFont("Arial", 12))
        band_label.setFixedWidth(110)
        self.band_combo = QComboBox()
        self.band_combo.addItems(["160m", "80m", "60m", "40m", "30m", "20m", "17m", "15m", "12m", "10m", "6m", "2m", "70cm"])
        self.band_combo.setStyleSheet("padding: 6px;")
        band_field.addWidget(band_label)
        band_field.addWidget(self.band_combo, 1)
        mode_layout.addLayout(band_field)
        
        # 频率
        freq_field = QHBoxLayout()
        freq_label = QLabel("频率:")
        freq_label.setFont(QFont("Arial", 12))
        freq_label.setFixedWidth(110)
        self.freq_input = QLineEdit()
        freq_field.addWidget(freq_label)
        freq_field.addWidget(self.freq_input, 1)
        mode_layout.addLayout(freq_field)
        
        form_layout.addLayout(mode_layout)
        
        # RST报告
        rst_layout = QHBoxLayout()
        
        # 发送报告
        sent_layout = QHBoxLayout()
        sent_label = QLabel("发送报告:")
        sent_label.setFont(QFont("Arial", 12))
        sent_label.setFixedWidth(158)
        self.rst_sent_input = QLineEdit()
        sent_layout.addWidget(sent_label)
        sent_layout.addWidget(self.rst_sent_input, 1)
        rst_layout.addLayout(sent_layout)
        
        # 接收报告
        recv_layout = QHBoxLayout()
        recv_label = QLabel("接收报告:")
        recv_label.setFont(QFont("Arial", 12))
        recv_label.setFixedWidth(158)
        self.rst_recv_input = QLineEdit()
        recv_layout.addWidget(recv_label)
        recv_layout.addWidget(self.rst_recv_input, 1)
        rst_layout.addLayout(recv_layout)
        
        form_layout.addLayout(rst_layout)
        
        # QSL状态
        qsl_layout = QHBoxLayout()
        
        # 发送状态
        sent_qsl_layout = QHBoxLayout()
        sent_qsl_label = QLabel("QSL发送:")
        sent_qsl_label.setFont(QFont("Arial", 12))
        sent_qsl_label.setFixedWidth(158)
        self.qsl_sent_combo = QComboBox()
        self.qsl_sent_combo.addItems(["未发送", "已发送", "已确认"])
        self.qsl_sent_combo.setStyleSheet("padding: 6px;")
        sent_qsl_layout.addWidget(sent_qsl_label)
        sent_qsl_layout.addWidget(self.qsl_sent_combo, 1)
        qsl_layout.addLayout(sent_qsl_layout)
        
        # 接收状态
        recv_qsl_layout = QHBoxLayout()
        recv_qsl_label = QLabel("QSL接收:")
        recv_qsl_label.setFont(QFont("Arial", 12))
        recv_qsl_label.setFixedWidth(158)
        self.qsl_recv_combo = QComboBox()
        self.qsl_recv_combo.addItems(["未收到", "已收到", "已确认"])
        self.qsl_recv_combo.setStyleSheet("padding: 6px;")
        recv_qsl_layout.addWidget(recv_qsl_label)
        recv_qsl_layout.addWidget(self.qsl_recv_combo, 1)
        qsl_layout.addLayout(recv_qsl_layout)
        
        form_layout.addLayout(qsl_layout)
        
        # 备注
        comment_layout = QHBoxLayout()
        comment_label = QLabel("备注:")
        comment_label.setFont(QFont("Arial", 12))
        comment_label.setFixedWidth(110)
        self.comment_input = QLineEdit()
        self.comment_input.setPlaceholderText("输入备注信息...")
        comment_layout.addWidget(comment_label)
        comment_layout.addWidget(self.comment_input, 1)
        form_layout.addLayout(comment_layout)
        
        layout.addWidget(form_frame)
        
        # 按钮
        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        
        self.add_btn = AnimatedButton("添加记录")
        self.add_btn.setFixedWidth(150)
        self.add_btn.clicked.connect(self.add_record)
        btn_layout.addWidget(self.add_btn)
        
        self.clear_btn = AnimatedButton("清空表单")
        self.clear_btn.setFixedWidth(150)
        self.clear_btn.setStyleSheet("background-color: #868e96;")
        self.clear_btn.clicked.connect(self.clear_form)
        btn_layout.addWidget(self.clear_btn)
        
        layout.addLayout(btn_layout)
        
        return page
    
    def create_stats_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setAlignment(Qt.AlignTop)
        
        title = QLabel("统计信息")
        title.setFont(QFont("Arial", 16, QFont.Bold))
        title.setStyleSheet("color: #3b5bdb; margin-bottom: 20px;")
        layout.addWidget(title)
        
        stats_frame = QFrame()
        stats_frame.setStyleSheet("""
            QFrame {
                background-color: #f8f9fa;
                border-radius: 15px;
                padding: 25px;
                border: 1px solid #dee2e6;
            }
        """)
        stats_layout = QVBoxLayout(stats_frame)
        
        # 总体统计
        total_layout = QHBoxLayout()
        total_layout.addWidget(QLabel("总记录数:"))
        self.total_label = QLabel()
        self.total_label.setFont(QFont("Arial", 14, QFont.Bold))
        total_layout.addWidget(self.total_label)
        total_layout.addStretch()
        stats_layout.addLayout(total_layout)
        
        # 按模式统计
        mode_title = QLabel("按模式统计:")
        mode_title.setFont(QFont("Arial", 12, QFont.Bold))
        stats_layout.addWidget(mode_title)
        
        self.mode_stats = QLabel()
        self.mode_stats.setStyleSheet("margin-left: 10px;")
        stats_layout.addWidget(self.mode_stats)
        
        # 按波段统计
        band_title = QLabel("按波段统计:")
        band_title.setFont(QFont("Arial", 12, QFont.Bold))
        stats_layout.addWidget(band_title)
        
        self.band_stats = QLabel()
        self.band_stats.setStyleSheet("margin-left: 10px;")
        stats_layout.addWidget(self.band_stats)
        
        # QSL状态统计
        qsl_title = QLabel("QSL状态统计:")
        qsl_title.setFont(QFont("Arial", 12, QFont.Bold))
        stats_layout.addWidget(qsl_title)
        
        self.qsl_stats = QLabel()
        self.qsl_stats.setStyleSheet("margin-left: 10px;")
        stats_layout.addWidget(self.qsl_stats)
        
        stats_layout.addStretch()
        
        layout.addWidget(stats_frame)
        
        # 刷新统计数据
        self.update_stats()
        
        return page
    
    def load_data(self):
        if os.path.exists(self.data_file):
            try:
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except:
                # 文件存在但读取失败时返回空列表
                return []
        # 文件不存在时返回空列表
        return []
    
    def save_data(self):
        with open(self.data_file, 'w', encoding='utf-8') as f:
            json.dump(self.data, f, ensure_ascii=False, indent=2)
    
    def refresh_table(self):
        self.table.setRowCount(0)
        
        for idx, record in enumerate(self.data):
            self.table.insertRow(idx)
            
            # 添加表格项
            self.table.setItem(idx, 0, QTableWidgetItem(str(record["id"])))
            self.table.setItem(idx, 1, QTableWidgetItem(record["call_sign"]))
            self.table.setItem(idx, 2, QTableWidgetItem(record["date"]))
            self.table.setItem(idx, 3, QTableWidgetItem(record["time"]))
            self.table.setItem(idx, 4, QTableWidgetItem(record["mode"]))
            self.table.setItem(idx, 5, QTableWidgetItem(record["band"]))
            self.table.setItem(idx, 6, QTableWidgetItem(record["frequency"]))
            self.table.setItem(idx, 7, QTableWidgetItem(record["rst_sent"]))
            self.table.setItem(idx, 8, QTableWidgetItem(record["rst_recv"]))
            
            # QSL状态特殊样式
            qsl_sent_item = QTableWidgetItem(record["qsl_sent"])
            if record["qsl_sent"] == "已发送":
                qsl_sent_item.setBackground(QColor("#fff3bf"))
            elif record["qsl_sent"] == "已确认":
                qsl_sent_item.setBackground(QColor("#d3f9d8"))
            self.table.setItem(idx, 9, qsl_sent_item)
            
            qsl_recv_item = QTableWidgetItem(record["qsl_recv"])
            if record["qsl_recv"] == "已收到":
                qsl_recv_item.setBackground(QColor("#fff3bf"))
            elif record["qsl_recv"] == "已确认":
                qsl_recv_item.setBackground(QColor("#d3f9d8"))
            self.table.setItem(idx, 10, qsl_recv_item)
            
            self.table.setItem(idx, 11, QTableWidgetItem(record["comment"]))
        
        self.statusBar().showMessage(f"已加载 {len(self.data)} 条通联记录")
        self.update_stats()
    
    def filter_logs(self):
        search_text = self.search_input.text().lower()
        
        for row in range(self.table.rowCount()):
            row_visible = False
            for col in range(self.table.columnCount()):
                item = self.table.item(row, col)
                if item and search_text in item.text().lower():
                    row_visible = True
                    break
            
            self.table.setRowHidden(row, not row_visible)
    
    def on_row_selected(self):
        selected = self.table.selectionModel().selectedRows()
        if selected:
            self.edit_btn.setEnabled(True)
            self.delete_btn.setEnabled(True)
            self.update_qsl_btn.setEnabled(True)
        else:
            self.edit_btn.setEnabled(False)
            self.delete_btn.setEnabled(False)
            self.update_qsl_btn.setEnabled(False)
    
    def add_record(self):
        # 获取表单数据
        call_sign = self.call_input.text().strip()
        date = self.date_input.date().toString("yyyy-MM-dd")
        time = self.time_input.text().strip()
        mode = self.mode_combo.currentText()
        band = self.band_combo.currentText()
        frequency = self.freq_input.text().strip()
        rst_sent = self.rst_sent_input.text().strip()
        rst_recv = self.rst_recv_input.text().strip()
        qsl_sent = self.qsl_sent_combo.currentText()
        qsl_recv = self.qsl_recv_combo.currentText()
        comment = self.comment_input.text().strip()
        
        # 验证必填字段
        if not call_sign:
            QMessageBox.warning(self, "输入错误", "呼号不能为空")
            return
        if not time:
            QMessageBox.warning(self, "输入错误", "时间不能为空")
            return
        if not frequency:
            QMessageBox.warning(self, "输入错误", "频率不能为空")
            return
        
        # 创建新记录
        new_id = max([r["id"] for r in self.data]) + 1 if self.data else 1
        new_record = {
            "id": new_id,
            "call_sign": call_sign,
            "date": date,
            "time": time,
            "mode": mode,
            "band": band,
            "frequency": frequency,
            "rst_sent": rst_sent,
            "rst_recv": rst_recv,
            "qsl_sent": qsl_sent,
            "qsl_recv": qsl_recv,
            "comment": comment
        }
        
        # 添加到数据
        self.data.append(new_record)
        self.save_data()
        
        # 刷新表格
        self.refresh_table()
        
        # 切换到日志页面
        self.stacked_widget.setCurrentIndex(0)
        
        # 清空表单
        self.clear_form()
        
        # 显示成功消息
        QMessageBox.information(self, "成功", "通联记录已成功添加")
    
    def clear_form(self):
        self.call_input.clear()
        self.date_input.setDate(QDate.currentDate())
        self.time_input.clear()
        self.mode_combo.setCurrentIndex(0)
        self.band_combo.setCurrentIndex(0)
        self.freq_input.clear()
        self.rst_sent_input.clear()
        self.rst_recv_input.clear()
        self.qsl_sent_combo.setCurrentIndex(0)
        self.qsl_recv_combo.setCurrentIndex(0)
        self.comment_input.clear()
    
    def edit_record(self):
        selected_row = self.table.currentRow()
        if selected_row >= 0:
            record_id = int(self.table.item(selected_row, 0).text())
            record = next((r for r in self.data if r["id"] == record_id), None)
            
            if record:
                # 填充到添加表单
                self.call_input.setText(record["call_sign"])
                self.date_input.setDate(QDate.fromString(record["date"], "yyyy-MM-dd"))
                self.time_input.setText(record["time"])
                self.mode_combo.setCurrentText(record["mode"])
                self.band_combo.setCurrentText(record["band"])
                self.freq_input.setText(record["frequency"])
                self.rst_sent_input.setText(record["rst_sent"])
                self.rst_recv_input.setText(record["rst_recv"])
                self.qsl_sent_combo.setCurrentText(record["qsl_sent"])
                self.qsl_recv_combo.setCurrentText(record["qsl_recv"])
                self.comment_input.setText(record["comment"])
                
                # 切换到添加页面
                self.stacked_widget.setCurrentIndex(1)
                
                # 更改按钮文本和功能
                self.add_btn.setText("更新记录")
                self.add_btn.clicked.disconnect()
                self.add_btn.clicked.connect(lambda: self.update_record(record_id))
    
    def update_record(self, record_id):
        # 获取表单数据
        call_sign = self.call_input.text().strip()
        date = self.date_input.date().toString("yyyy-MM-dd")
        time = self.time_input.text().strip()
        mode = self.mode_combo.currentText()
        band = self.band_combo.currentText()
        frequency = self.freq_input.text().strip()
        rst_sent = self.rst_sent_input.text().strip()
        rst_recv = self.rst_recv_input.text().strip()
        qsl_sent = self.qsl_sent_combo.currentText()
        qsl_recv = self.qsl_recv_combo.currentText()
        comment = self.comment_input.text().strip()
        
        # 验证必填字段
        if not call_sign:
            QMessageBox.warning(self, "输入错误", "呼号不能为空")
            return
        if not time:
            QMessageBox.warning(self, "输入错误", "时间不能为空")
            return
        if not frequency:
            QMessageBox.warning(self, "输入错误", "频率不能为空")
            return
        
        # 更新记录
        for record in self.data:
            if record["id"] == record_id:
                record.update({
                    "call_sign": call_sign,
                    "date": date,
                    "time": time,
                    "mode": mode,
                    "band": band,
                    "frequency": frequency,
                    "rst_sent": rst_sent,
                    "rst_recv": rst_recv,
                    "qsl_sent": qsl_sent,
                    "qsl_recv": qsl_recv,
                    "comment": comment
                })
                break
        
        self.save_data()
        self.refresh_table()
        
        # 切换到日志页面
        self.stacked_widget.setCurrentIndex(0)
        
        # 重置按钮
        self.add_btn.setText("添加记录")
        self.add_btn.clicked.disconnect()
        self.add_btn.clicked.connect(self.add_record)
        
        # 清空表单
        self.clear_form()
        
        QMessageBox.information(self, "成功", "记录已更新")
    
    def delete_record(self):
        selected_row = self.table.currentRow()
        if selected_row >= 0:
            record_id = int(self.table.item(selected_row, 0).text())
            
            reply = QMessageBox.question(
                self, "确认删除", 
                "确定要删除这条记录吗？此操作不可恢复。", 
                QMessageBox.Yes | QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.data = [r for r in self.data if r["id"] != record_id]
                self.save_data()
                self.refresh_table()
                QMessageBox.information(self, "成功", "记录已删除")
    
    def update_qsl_status(self):
        selected_row = self.table.currentRow()
        if selected_row >= 0:
            record_id = int(self.table.item(selected_row, 0).text())
            record = next((r for r in self.data if r["id"] == record_id), None)
            
            if record:
                # 创建对话框更新QSL状态
                dialog = QDialog(self)
                dialog.setWindowTitle("更新QSL状态")
                dialog.setFixedSize(400, 300)
                dialog.setStyleSheet("""
                    QDialog {
                        background-color: #f8f9fa;
                        border-radius: 10px;
                    }
                """)
                
                layout = QVBoxLayout(dialog)
                
                title = QLabel(f"更新呼号 {record['call_sign']} 的QSL状态")
                title.setFont(QFont("Arial", 12, QFont.Bold))
                title.setAlignment(Qt.AlignCenter)
                title.setStyleSheet("color: #3b5bdb; margin-bottom: 20px;")
                layout.addWidget(title)
                
                form_layout = QVBoxLayout()
                form_layout.setContentsMargins(20, 0, 20, 20)
                
                # QSL发送状态
                sent_layout = QHBoxLayout()
                sent_label = QLabel("QSL发送状态:")
                sent_label.setFont(QFont("Arial", 10))
                sent_status_combo = QComboBox()
                sent_status_combo.addItems(["未发送", "已发送", "已确认"])
                sent_status_combo.setCurrentText(record["qsl_sent"])
                sent_status_combo.setStyleSheet("padding: 6px;")
                sent_layout.addWidget(sent_label)
                sent_layout.addWidget(sent_status_combo, 1)
                form_layout.addLayout(sent_layout)
                
                # QSL接收状态
                recv_layout = QHBoxLayout()
                recv_label = QLabel("QSL接收状态:")
                recv_label.setFont(QFont("Arial", 10))
                recv_status_combo = QComboBox()
                recv_status_combo.addItems(["未收到", "已收到", "已确认"])
                recv_status_combo.setCurrentText(record["qsl_recv"])
                recv_status_combo.setStyleSheet("padding: 6px;")
                recv_layout.addWidget(recv_label)
                recv_layout.addWidget(recv_status_combo, 1)
                form_layout.addLayout(recv_layout)
                
                layout.addLayout(form_layout)
                
                # 按钮
                btn_layout = QHBoxLayout()
                btn_layout.addStretch()
                
                save_btn = AnimatedButton("保存")
                save_btn.clicked.connect(dialog.accept)
                btn_layout.addWidget(save_btn)
                
                cancel_btn = AnimatedButton("取消")
                cancel_btn.setStyleSheet("background-color: #868e96;")
                cancel_btn.clicked.connect(dialog.reject)
                btn_layout.addWidget(cancel_btn)
                
                layout.addLayout(btn_layout)
                
                if dialog.exec_() == QDialog.Accepted:
                    record["qsl_sent"] = sent_status_combo.currentText()
                    record["qsl_recv"] = recv_status_combo.currentText()
                    self.save_data()
                    self.refresh_table()
                    QMessageBox.information(self, "成功", "QSL状态已更新")
    
    def update_stats(self):
        # 确保标签已创建
        if not hasattr(self, 'total_label'):
            return
            
        # 总记录数
        self.total_label.setText(str(len(self.data)))
        
        # 按模式统计
        mode_counts = {}
        for record in self.data:
            mode = record["mode"]
            mode_counts[mode] = mode_counts.get(mode, 0) + 1
        
        mode_text = ""
        for mode, count in mode_counts.items():
            mode_text += f"{mode}: {count} 条记录\n"
        self.mode_stats.setText(mode_text)
        
        # 按波段统计
        band_counts = {}
        for record in self.data:
            band = record["band"]
            band_counts[band] = band_counts.get(band, 0) + 1
        
        band_text = ""
        for band, count in band_counts.items():
            band_text += f"{band}: {count} 条记录\n"
        self.band_stats.setText(band_text)
        
        # QSL状态统计
        sent_stats = {"未发送": 0, "已发送": 0, "已确认": 0}
        recv_stats = {"未收到": 0, "已收到": 0, "已确认": 0}
        
        for record in self.data:
            # 确保发送状态是有效值
            sent_status = record["qsl_sent"]
            if sent_status in sent_stats:
                sent_stats[sent_status] += 1
            else:
                # 处理无效值
                sent_stats["未发送"] += 1
                record["qsl_sent"] = "未发送"
            
            # 确保接收状态是有效值
            recv_status = record["qsl_recv"]
            if recv_status in recv_stats:
                recv_stats[recv_status] += 1
            else:
                # 处理无效值
                recv_stats["未收到"] += 1
                record["qsl_recv"] = "未收到"
        
        qsl_text = "发送状态:\n"
        for status, count in sent_stats.items():
            qsl_text += f"  {status}: {count} 条\n"
        
        qsl_text += "\n接收状态:\n"
        for status, count in recv_stats.items():
            qsl_text += f"  {status}: {count} 条"
        
        self.qsl_stats.setText(qsl_text)
        
        # 保存清理后的数据
        self.save_data()
    
    def export_data(self):
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出数据", "", "JSON Files (*.json);;All Files (*)"
        )
        
        if file_path:
            if not file_path.endswith('.json'):
                file_path += '.json'
            
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(self.data, f, ensure_ascii=False, indent=2)
                QMessageBox.information(self, "成功", "数据已成功导出")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"导出数据时出错: {str(e)}")
    
    def import_data(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "导入数据", "", "JSON Files (*.json);;All Files (*)"
        )
        
        if file_path:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    new_data = json.load(f)
                
                # 合并数据，更新ID
                max_id = max([r["id"] for r in self.data]) if self.data else 0
                for record in new_data:
                    max_id += 1
                    record["id"] = max_id
                    self.data.append(record)
                
                # 清理导入的数据
                self.clean_data()
                
                self.save_data()
                self.refresh_table()
                QMessageBox.information(self, "成功", f"已成功导入 {len(new_data)} 条记录")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"导入数据时出错: {str(e)}")
    
    def show_about(self):
        about_text = """
        <h2 style="color: #3b5bdb;">HamLogger 通联日志管理软件</h2>
        <p></p>
        <a href="https://gitee.com/neyume/HamLogger">开源地址（Gitee）</a>
        <p>本软件基于GPL-3.0许可证开源，请在遵循该许可证的前提下对本软件进行修改、分发等操作。
</p>
        """
        
        msg = QMessageBox()
        msg.setWindowTitle("关于软件")
        msg.setTextFormat(Qt.RichText)
        msg.setText(about_text)
        msg.setIconPixmap(self.create_app_icon().scaled(64, 64, Qt.KeepAspectRatio, Qt.SmoothTransformation))
        msg.exec_()
    
    def closeEvent(self, event):
        # 保存数据
        self.save_data()
        
        # 显示退出消息
        reply = QMessageBox.question(
            self, "退出程序",
            "确定要退出程序吗？所有数据已保存。",
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 设置应用样式
    app.setStyle("Fusion")
    
    # 设置调色板
    palette = QPalette()
    palette.setColor(QPalette.Window, QColor(240, 245, 255))
    palette.setColor(QPalette.WindowText, QColor(33, 37, 41))
    palette.setColor(QPalette.Base, QColor(255, 255, 255))
    palette.setColor(QPalette.AlternateBase, QColor(248, 249, 250))
    palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255))
    palette.setColor(QPalette.ToolTipText, QColor(33, 37, 41))
    palette.setColor(QPalette.Text, QColor(33, 37, 41))
    palette.setColor(QPalette.Button, QColor(248, 249, 250))
    palette.setColor(QPalette.ButtonText, QColor(33, 37, 41))
    palette.setColor(QPalette.BrightText, Qt.red)
    palette.setColor(QPalette.Highlight, QColor(92, 124, 250))
    palette.setColor(QPalette.HighlightedText, Qt.white)
    app.setPalette(palette)
    
    # 设置全局字体
    font = QFont("Arial", 10)
    app.setFont(font)
    
    window = QSOLogger()
    window.show()
    sys.exit(app.exec_())